/**
 *
 */
package com.ruoyi.web.controller.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.PutMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.httpclient.params.HttpMethodParams;

/**
 * Http 请求工具类
 * 
 * @author chenjiuchang
 * 
 *         2022年08月26日
 */
public class HttpUtil {

	// 多线程使用
	private static MultiThreadedHttpConnectionManager connectionManager = null;

	static {
		connectionManager = new MultiThreadedHttpConnectionManager();

		HttpConnectionManagerParams managerParams = connectionManager.getParams();
		// 每个host的最大连接数
		managerParams.setDefaultMaxConnectionsPerHost(10);
		// 总的连接数
		managerParams.setMaxTotalConnections(300);
		// 设置连接超时时间(单位毫秒)
		managerParams.setConnectionTimeout(5000);
		// 设置等待数据超时时间(单位毫秒)
		managerParams.setSoTimeout(15000);
	}

	public static Map<String, String> getHeaderMap(String headerName, String headerValue) {
		Map<String, String> header = new HashMap<String, String>();
		header.put("headerName", headerName);
		header.put("headerValue", headerValue);
		return header;
	}

	/**
	 * warn: org.apache.commons.httpclient.HttpMethodBase - Going to buffer response
	 * body of large or unknown size. Using getResponseBodyAsStream instead is
	 * recommended.
	 * 
	 * @param httpMethod
	 * @return
	 * @throws IOException
	 */
	private static String getResponseBodyAsString(HttpMethod httpMethod) throws IOException {
		BufferedReader reader = new BufferedReader(new InputStreamReader(httpMethod.getResponseBodyAsStream()));
		StringBuffer stringBuffer = new StringBuffer();
		String str = "";
		while ((str = reader.readLine()) != null) {
			stringBuffer.append(str);
		}
		String ts = stringBuffer.toString();
		return ts;
	}

	/**
	 * POST 请求
	 * 
	 * @param url       发送请求的URL
	 * @param rawParams 请求参数
	 * @return 服务器响应字符串
	 * @throws Exception
	 */
	public static String postRequest(String url, Map<String, String> rawParams) {
		return postRequest(url, rawParams, null);
	}

	/**
	 * POST 请求
	 * 
	 * @param url       发送请求的URL
	 * @param rawParams 请求参数
	 * @param headMaps  请求头部
	 * @return
	 */
	public static String postRequest(String url, Map<String, String> rawParams, List<Map<String, String>> headMaps) {
		return postRequest(url, rawParams, null, headMaps);
	}

	/**
	 * POST 请求
	 * 
	 * @param url
	 * @param rawParams 请求参数
	 * @param encode    默认utf-8
	 * @param headMaps  请求头部
	 * @return
	 */
	public static String postRequest(String url, Map<String, String> rawParams, String encode,
			List<Map<String, String>> headMaps) {
		encode = encode == null ? "utf-8" : encode;

		HttpClient httpClient = new HttpClient(connectionManager);
		PostMethod postMethod = null;
		String result = null;
		try {
			postMethod = new PostMethod(url);
			if (rawParams != null) {
				for (String key : rawParams.keySet()) {
					if (key != null && rawParams.get(key) != null) {
						postMethod.setParameter(key, rawParams.get(key));
					}
					System.out.println("kp : " + key + " : " + rawParams.get(key));
				}
			}
			if (headMaps != null) {
				for (Map<String, String> headMap : headMaps) {
					postMethod.setRequestHeader(headMap.get("headerName"), headMap.get("headerValue"));
				}
			}
			postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encode);
			httpClient.executeMethod(postMethod);
			result = getResponseBodyAsString(postMethod);

			System.out.println("post " + url + " : " + postMethod.getStatusCode() + " > " + result);
		} catch (Exception e) {
			
		} finally {
			postMethod.releaseConnection();
		}
		return result;
	}

	/**
	 * POST 请求
	 * 
	 * @param url
	 * @param requestBody 请求body
	 * @return
	 */
	public static String postRequestEntity(String url, String requestBody) {
		return postRequestEntity(url, requestBody, null);
	}

	/**
	 * POST 请求
	 * 
	 * @param url
	 * @param requestBody 请求body
	 * @param headMaps    请求头部
	 * @return
	 */
	public static String postRequestEntity(String url, String requestBody, List<Map<String, String>> headMaps) {
		return postRequestEntity(url, requestBody, headMaps, null, null);
	}

	/**
	 * POST 请求
	 * 
	 * @param requestBody 请求body
	 * @param headMaps    请求头部
	 * @param contentType 默认 application/json , 可选 application/xml
	 * @param encode      默认 utf-8
	 * @return
	 */
	public static String postRequestEntity(String url, String requestBody, List<Map<String, String>> headMaps,
			String contentType, String encode) {
		return requestEntity(url, requestBody, headMaps, contentType, encode, new PostMethod(url));
	}

	/**
	 * PUT 请求
	 * 
	 * @param url
	 * @param requestBody 请求body
	 * @return
	 */
	public static String putRequestEntity(String url, String requestBody) {
		return putRequestEntity(url, requestBody, null);
	}

	/**
	 * PUT 请求
	 * 
	 * @param url
	 * @param requestBody 请求body
	 * @param headMaps    请求头部
	 * @return
	 */
	public static String putRequestEntity(String url, String requestBody, List<Map<String, String>> headMaps) {
		return putRequestEntity(url, requestBody, headMaps, null, null);
	}

	/**
	 * PUT 请求
	 * 
	 * @param url
	 * @param requestBody 请求body
	 * @param headMaps    请求头部
	 * @param contentType 默认 application/json , 可选 application/xml
	 * @param encode      默认 utf-8
	 * @return
	 */
	public static String putRequestEntity(String url, String requestBody, List<Map<String, String>> headMaps,
			String contentType, String encode) {

		return requestEntity(url, requestBody, headMaps, contentType, encode, new PutMethod(url));
	}

	public static String requestEntity(String url, String requestBody, List<Map<String, String>> headMaps,
			String contentType, String encode, EntityEnclosingMethod postMethod) {
		contentType = contentType == null ? "application/json" : contentType;
		encode = encode == null ? "utf-8" : encode;

		HttpClient httpClient = new HttpClient(connectionManager);
		String result = null;
		try {
			RequestEntity requestEntity = new StringRequestEntity(requestBody, contentType, encode);

			postMethod.setRequestEntity(requestEntity);

			if (headMaps != null) {
				for (Map<String, String> headMap : headMaps) {
					postMethod.setRequestHeader(headMap.get("headerName"), headMap.get("headerValue"));
				}
			}
			postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, encode);
			httpClient.executeMethod(postMethod);
			result = getResponseBodyAsString(postMethod);

			System.out.println("requestEntity " + url + " : " + postMethod.getStatusCode() + " > " + result);
		} catch (Exception e) {
			
		} finally {
			postMethod.releaseConnection();
		}

		return result;
	}

	 /**
     * Http get请求
     * @param httpUrl 连接
     * @return 响应数据
     */
    public static String doGet(String httpUrl){
        //链接
        HttpURLConnection connection = null;
        InputStream is = null;
        BufferedReader br = null;
        StringBuffer result = new StringBuffer();
        try {
            //创建连接
            URL url = new URL(httpUrl);
            connection = (HttpURLConnection) url.openConnection();
            //设置请求方式
            connection.setRequestMethod("GET");
            //设置连接超时时间
            connection.setReadTimeout(15000);
            //开始连接
            connection.connect();
            //获取响应数据
            if (connection.getResponseCode() == 200) {
                //获取返回的数据
                is = connection.getInputStream();
                if (null != is) {
                    br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                    String temp = null;
                    while (null != (temp = br.readLine())) {
                        result.append(temp);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != br) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != is) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            //关闭远程连接
            connection.disconnect();
        }
        return result.toString();
    }
}
